/////////////////////////////////////////////////////////////////////////////
// Name:        RemovePkgDialog.cpp
// Purpose:     
// Author:      yospaly
// Modified by: 
// Created:     14/01/2009 17:26:40
// RCS-ID:      
// Copyright:   Copyright (C) 2008, yospaly
// Licence:     
/////////////////////////////////////////////////////////////////////////////

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

////@begin includes
////@end includes

#include "MaintainPkgDialog.h"
#include "events.h"
#include "scriptrunner.h"
#include "pkgmgr.h"

////@begin XPM images
////@end XPM images


/*!
 * MaintainPkgDialog type definition
 */

IMPLEMENT_DYNAMIC_CLASS( MaintainPkgDialog, wxDialog )


/*!
 * MaintainPkgDialog event table definition
 */

BEGIN_EVENT_TABLE( MaintainPkgDialog, wxDialog )

////@begin MaintainPkgDialog event table entries
////@end MaintainPkgDialog event table entries

	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKG_REMOVE_BEGIN_EVENT, MaintainPkgDialog::OnPkgRemoveBegin)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKG_REMOVING_EVENT, MaintainPkgDialog::OnPkgRemoving)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKG_REMOVE_COMPLETED_EVENT, MaintainPkgDialog::OnPkgRemoveCompleted)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKGS_REMOVE_BEGIN_EVENT, MaintainPkgDialog::OnPkgsRemoveBegin)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKGS_REMOVE_COMPLETED_EVENT, MaintainPkgDialog::OnPkgsRemoveCompleted)
	
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKG_INSTALL_BEGIN_EVENT, MaintainPkgDialog::OnPkgInstallBegin)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKG_INSTALLING_EVENT, MaintainPkgDialog::OnPkgInstalling)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKG_INSTALL_COMPLETED_EVENT, MaintainPkgDialog::OnPkgInstallCompleted)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKGS_INSTALL_BEGIN_EVENT, MaintainPkgDialog::OnPkgsInstallBegin)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKGS_INSTALL_COMPLETED_EVENT, MaintainPkgDialog::OnPkgsInstallCompleted)
	
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_RUN_PREREMOVE_SCRIPT_EVENT, MaintainPkgDialog::OnRunPreremoveScript)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_RUN_POSTINSTALL_SCRIPT_EVENT, MaintainPkgDialog::OnRunPostinstallScript)
	
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKGS_MAINTIAN_BEGIN_EVENT, MaintainPkgDialog::OnPkgsMaintainBegin)
	EVT_COMMAND( ID_MAINTAIN_PKG_DIALOG, wxEVT_PKGS_MAINTIAN_COMPLETED_EVENT, MaintainPkgDialog::OnPkgsMaintainCompleted)
	
END_EVENT_TABLE()


/*!
 * MaintainPkgDialog constructors
 */

MaintainPkgDialog::MaintainPkgDialog()
{
    Init();
}

MaintainPkgDialog::MaintainPkgDialog( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
    Init();
    Create(parent, id, caption, pos, size, style);
}


/*!
 * RemovePkgDialog creator
 */

bool MaintainPkgDialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
////@begin MaintainPkgDialog creation
    SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
    wxDialog::Create( parent, id, caption, pos, size, style );

    CreateControls();
    Centre();
////@end MaintainPkgDialog creation
    return true;
}


/*!
 * MaintainPkgDialog destructor
 */

MaintainPkgDialog::~MaintainPkgDialog()
{
////@begin MaintainPkgDialog destruction
////@end MaintainPkgDialog destruction
    EventCenter::get().unregister(this);
}


/*!
 * Member initialisation
 */

void MaintainPkgDialog::Init()
{
////@begin MaintainPkgDialog member initialisation
    p_details_textctrl = NULL;
    p_maintain_status_static = NULL;
    p_progress_gauge = NULL;
    p_ok_button = NULL;
    p_cancel_button = NULL;
////@end MaintainPkgDialog member initialisation
}


/*!
 * Control creation for RemovePkgDialog
 */

void MaintainPkgDialog::CreateControls()
{    
////@begin MaintainPkgDialog content construction
    MaintainPkgDialog* itemDialog1 = this;

    wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
    itemDialog1->SetSizer(itemBoxSizer2);

    wxStaticText* itemStaticText3 = new wxStaticText( itemDialog1, wxID_STATIC, _("Package maintaining details :"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer2->Add(itemStaticText3, 0, wxGROW|wxALL, 5);

    p_details_textctrl = new wxTextCtrl( itemDialog1, ID_DETAILS_TEXTCTRL, _T(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH2|wxTE_AUTO_URL|wxHSCROLL );
    itemBoxSizer2->Add(p_details_textctrl, 1, wxGROW|wxALL, 5);

    p_maintain_status_static = new wxStaticText( itemDialog1, wxID_STATIC, _("Maintaining ..."), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer2->Add(p_maintain_status_static, 0, wxGROW|wxALL, 5);

    p_progress_gauge = new wxGauge( itemDialog1, ID_PROGRESS_GAUGE, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL );
    p_progress_gauge->SetValue(0);
    itemBoxSizer2->Add(p_progress_gauge, 0, wxGROW|wxALL, 5);

    wxStdDialogButtonSizer* itemStdDialogButtonSizer7 = new wxStdDialogButtonSizer;

    itemBoxSizer2->Add(itemStdDialogButtonSizer7, 0, wxALIGN_RIGHT|wxALL, 5);
    p_ok_button = new wxButton( itemDialog1, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
    p_ok_button->Enable(false);
    itemStdDialogButtonSizer7->AddButton(p_ok_button);

    p_cancel_button = new wxButton( itemDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
    itemStdDialogButtonSizer7->AddButton(p_cancel_button);

    itemStdDialogButtonSizer7->Realize();

////@end MaintainPkgDialog content construction
    EventCenter::registerr(wxEVT_PKG_REMOVE_BEGIN_EVENT, this);
    EventCenter::registerr(wxEVT_PKG_REMOVING_EVENT, this);
    EventCenter::registerr(wxEVT_PKG_REMOVE_COMPLETED_EVENT, this);
    EventCenter::registerr(wxEVT_PKGS_REMOVE_BEGIN_EVENT, this);
    EventCenter::registerr(wxEVT_PKGS_REMOVE_COMPLETED_EVENT, this);
    
    EventCenter::registerr(wxEVT_PKG_INSTALL_BEGIN_EVENT, this);
	EventCenter::registerr(wxEVT_PKG_INSTALLING_EVENT, this);
	EventCenter::registerr(wxEVT_PKG_INSTALL_COMPLETED_EVENT, this);
	EventCenter::registerr(wxEVT_PKGS_INSTALL_BEGIN_EVENT, this);
	EventCenter::registerr(wxEVT_PKGS_INSTALL_COMPLETED_EVENT, this);
	
    EventCenter::registerr(wxEVT_RUN_PREREMOVE_SCRIPT_EVENT, this);
    EventCenter::registerr(wxEVT_RUN_POSTINSTALL_SCRIPT_EVENT, this);

    EventCenter::registerr(wxEVT_PKGS_MAINTIAN_BEGIN_EVENT, this);
    EventCenter::registerr(wxEVT_PKGS_MAINTIAN_COMPLETED_EVENT, this);
    
    // Keep original system font size
    wxFont font = p_details_textctrl->GetFont();
    font.SetFaceName(_T("Courier New"));
    p_details_textctrl->SetFont(font);
}


/*!
 * Should we show tooltips?
 */

bool MaintainPkgDialog::ShowToolTips()
{
    return true;
}

/*!
 * Get bitmap resources
 */

wxBitmap MaintainPkgDialog::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
////@begin MaintainPkgDialog bitmap retrieval
    wxUnusedVar(name);
    return wxNullBitmap;
////@end MaintainPkgDialog bitmap retrieval
}

/*!
 * Get icon resources
 */

wxIcon MaintainPkgDialog::GetIconResource( const wxString& name )
{
    // Icon retrieval
////@begin MaintainPkgDialog icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
////@end MaintainPkgDialog icon retrieval
}


void MaintainPkgDialog::OnPkgRemoveBegin(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("==> Removing package : "));
	p_details_textctrl->AppendText(event.GetString());
	p_details_textctrl->AppendText(_T("\n"));
}
void MaintainPkgDialog::OnPkgRemoving(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("    Delete "));
	p_details_textctrl->AppendText(event.GetString());
	p_details_textctrl->AppendText(_T("\n"));
	// p_progress_gauge->Pulse();
}
void MaintainPkgDialog::OnPkgRemoveCompleted(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("\n---------------------------------\n\n"));
	p_progress_gauge->SetValue(event.GetInt());
}
void MaintainPkgDialog::OnPkgsRemoveBegin(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("Begin remove packages :\n\n"));
	p_details_textctrl->AppendText(_T("---------------------------------\n\n"));
	p_progress_gauge->SetRange(event.GetInt());
}
void MaintainPkgDialog::OnPkgsRemoveCompleted(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("Packages removal have completed!"));
	p_details_textctrl->AppendText(_T("\n"));
}

void MaintainPkgDialog::OnPkgInstallBegin(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("==> Installing package : "));
	p_details_textctrl->AppendText(event.GetString());
	p_details_textctrl->AppendText(_T("\n"));
}
void MaintainPkgDialog::OnPkgInstalling(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("    Extract "));
	p_details_textctrl->AppendText(event.GetString());
	p_details_textctrl->AppendText(_T("\n"));
	// p_progress_gauge->Pulse();
}
void MaintainPkgDialog::OnPkgInstallCompleted(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("\n---------------------------------\n\n"));
	p_progress_gauge->SetValue(event.GetInt());
}
void MaintainPkgDialog::OnPkgsInstallBegin(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("Begin install packages :\n\n"));
	p_details_textctrl->AppendText(_T("---------------------------------\n\n"));
	p_progress_gauge->SetRange(event.GetInt());
}
void MaintainPkgDialog::OnPkgsInstallCompleted(wxCommandEvent &event) {
	p_details_textctrl->AppendText(_T("Packages installation have completed!"));
	p_details_textctrl->AppendText(_T("\n"));
}


void MaintainPkgDialog::OnRunPreremoveScript(wxCommandEvent &event) {
	const wxString& pkg = event.GetString();
	int err = event.GetInt();
	_run_script(pkg, err, false);
}
void MaintainPkgDialog::OnRunPostinstallScript(wxCommandEvent &event) {
	const wxString& pkg = event.GetString();
	int err = event.GetInt();
	_run_script(pkg, err, true);
}
void MaintainPkgDialog::OnPkgsMaintainBegin(wxCommandEvent &event) {
	
}
void MaintainPkgDialog::OnPkgsMaintainCompleted(wxCommandEvent &event) {
	p_maintain_status_static->SetLabel(_("Packages maintain task completed!"));
	p_cancel_button->Disable();
	p_ok_button->Enable();
}

void MaintainPkgDialog::_run_script(const wxString& pkg, int err, bool postinstall) {
    wxArrayString output;
    wxArrayString errors;
    
    // show a busy cursor
    wxBusyCursor();
    
	ScriptRunner::get().init_run_script();
	long ret = 0;
	
	if ( postinstall ) {
	    p_details_textctrl->AppendText(wxString::Format(
	    		_("==> Running postinstall script %s.sh ... "), pkg.c_str() ) );
		ret = ScriptRunner::get().run_postinstall_script(pkg, output, errors);
	} else {
	    p_details_textctrl->AppendText(_("Running preremove script ... "));
		ret = ScriptRunner::get().run_preremove_script(pkg, output, errors);
	}
	
	if ( ScriptRunner::SCRIPT_NOT_FOUND == ret ) {
		p_details_textctrl->AppendText(_("not found\n") );
	} else if (ScriptRunner::EXEC_SUCCESS == ret) {
		p_details_textctrl->AppendText(_("successful\n") );
	} else {
		p_details_textctrl->AppendText( wxString::Format(_("error code : %d\n"), err ) );
	}
	
	for ( int i=0; i<output.GetCount(); i++ ) {
		p_details_textctrl->AppendText(_("\t") );
		p_details_textctrl->AppendText(output[i]);
		p_details_textctrl->AppendText(_("\n") );
	}
	for ( int i=0; i<errors.GetCount(); i++ ) {
		p_details_textctrl->AppendText(_("\t") );
		p_details_textctrl->AppendText(errors[i]);
		p_details_textctrl->AppendText(_("\n") );
	}
	
	if ( postinstall ) {
	    p_details_textctrl->AppendText(_("\n---------------------------------\n\n") );
	} else {
		// pass
	}
	
	PkgMgr::get().end_run_script();
}
